-- dbtable用于存储数据 key=为redisKey value=为stocK
-- addtable用于存储本次出入库的key及对应的数量
-- keyList 用于存储本次的所有key
-- 切割函数 str为需要切割的字符串 symbol为切割符号,mytable为需要存放的表
-- 注意: 例如 str = 1/2 symbol=/时 切割只能拿到1 也就是说这饿方法只能拿到特殊符号前的字符 所以拼接时要注意特殊符号的拼接
local array = {}
local function split(str,symbol)
local i = 1;
    for item in string.gmatch( str,"(.-)"..symbol) do
        array[i] = item
        i = i+1;
    end
end
--请求锁是否存在
local productLocks =  redis.call('SMEMBERS', KEYS[1])
--需要添加到redis中的数据(即数据库中的库存数量) 所有属于都在次list中 key + "/" + addNum + "/" + dbNUm + "/"
local needAddMapTab = ARGV
--先将数据库中的数据和本次出入库的数据转为table格式
local dbData = {}
local addData = {}
--本次所有key数据
local keyList = {}

for i, iv in ipairs(needAddMapTab) do
        split(iv,"ø/ø")
        -- array[1]为key 2为新加数量 3 为数据库数量
       local ss = array[1]
       local dd = array[2]
       local ff = array[3]
        -- 获取出来 再放入table中 否则放入的会是个地址值
        -- 将所需数据封装为table和list
        dbData[ss] = ff
        addData[ss] = dd
        table.insert(keyList,ss)
    end
--需要重新插入到reids的table
local newtable = {}
--如果请求锁不存在 则直接将本需要插入redis的数据 相减后直接插入redis中
if productLocks == nil
    then
    --循环keyList相减校验是否能出库 能的话将相减之后的值塞入redis
    for k, kv in ipairs(keyList) do
       local daNum = dbData[kv]
       local addNum = addData[kv]
       if  daNum ~= nil and addNum ~=nil and (daNum - addNum) >= 0
          then
            newtable[kv] = (daNum - addNum)
       else
            return false
       end
    end
       --全部符合后将减掉之后的数据塞入redis
       redis.call("SADD", KEYS[1], newtable)
       return true
--如果锁已经存在 循环本次所有的key 然后从redis的table中get 如果不为空就用redis中的相减 如果为空就用传进来的数据库数据相减
else
    --先获取redis中的数据
--     local productStock = redis.call('SMEMBERS', KEYS[1])
    for m, mv in ipairs(keyList) do
            --本次添加的数量
            local addNum = tonumber(addData[mv])
            if addNum ~= nil
                then
                --根据key 从redis中数据获取 如果有直接用redis中的减 如果获取的为空 则用数据库中的
                if productLocks[mv] == nil
                    then
                    local dbNum = tonumber(dbData[mv])
                    if dbNum ~= nil and (dbNum - addNum) >= 0
                        then
                        productLocks[mv] = (dbNum - addNum)
                    else
                        return false
                    end
                else
                    --如果有则直接用redis中的
                    local redisNum = tonumber(productLocks[mv])
                    if redisNum ~= nil and (redisNum - addNum) >= 0
                        then
                         productLocks[mv] = (redisNum - addNum)
                    else
                        return false
                    end
                end
            else
                return false
            end
    end
    redis.call('setex', KEYS[1], 28800, productLocks)
    return true
end





